home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
system
/
np100.zip
/
NP.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-11-30
|
7KB
|
362 lines
;History:38,1
comment !
* Copyright 1988 By Russell Nelson. Don't try to make money off of it, and
* don't pretend that you wrote it.
*
* Compu$erve: 70441,205
* GEnie: BH01
* Internet: nelson@clutx.clarkson.edu
* BITNET: NELSON@CLUTX
* Fido/Opus: Russ Nelson@1:260/360
!
code segment public
assume cs:code, ds:code
org 2ch
phd_environ dw ?
org 5ch
phd_fcb1 label byte
org 100h
start:
jmp start_1
went_tsr db ? ;non-zero if a previous cmd went TSR.
first_one dw 0 ;segment of line buffer.
highest_phd dw ? ;address of highest phd we've seen.
not_yet_flag db ? ;='.' if we should print this one.
done_one db ? ;non-zero if we've printed a program
; name and hence should skip command.com
command db 'COMMAND.' ;name of command.com
assume ds:nothing
compare_command:
mov di,offset command ;point to command.com.
compare:
;enter with ds:bp -> name to test, cs:di -> name to test it against.
;exit with zr if they're equal, nz if not equal.
mov si,bp
compare_0:
lodsb ;compare two characters.
call tolower
cmp cs:[di],al
jne compare_1 ;give up if they're different.
cmp al,'.' ;success when we hit the extension.
je compare_1
inc di
jmp compare_0
compare_1:
ret
tolower:
cmp al,'a' ;Uppercase letter.
jb tolower_2
cmp al,'z'
ja tolower_2
sub al,20h
tolower_2:
ret
print_name:
;enter with ds:si -> name of a loaded program.
;
;find where the pathname ends and the filename begins.
;
print_name_3:
mov bp,si ;remember where we should print from.
print_name_1:
lodsb
cmp al,'\' ;restart if we hit either path separator.
je print_name_3
cmp al,'/'
je print_name_3
or al,al ;continue until we hit the end of the string.
jne print_name_1
;
; Should we store because of a TSR?
;
cmp went_tsr,0 ;should we use this as the last TSR?
jne print_tsr ;not yet - go test to see if we should.
;
; Have we reached the last TSR yet?
;
cmp not_yet_flag,'.' ;should we print yet?
jne print_test ;not yet - go test to see if we should.
;
; Did we just print a program? If so, we can skip the [COMMAND] that follows
; it. Otherwise, we should print [COMMAND].
;
xor al,al ;get and reset done_one
xchg al,done_one
or al,al ;did we just do a program?
je print_name_6 ;no - we can print [COMMAND] here.
;
; Avoid printing [COMMAND] immediately after a program that spawned command.com.
;
call compare_command ;compare command.com to the current one.
je print_name_2 ;go if they're equal.
print_name_6:
;
;print their name.
;
mov si,bp ;now restart after the rightmost slash.
mov dl,'['
mov ah,2
int 21h
print_name_4:
lodsb
or al,al ;give up when we hit the end.
je print_name_5
cmp al,'.' ;give up when we hit the extension.
je print_name_5
mov dl,al
mov ah,2
int 21h
jmp print_name_4
print_name_5:
mov dl,']'
mov ah,2
int 21h
;
; If we just printed a program, remember it in done_one.
;
call compare_command ;compare it to the current one.
je print_name_2 ;go if they're equal.
inc done_one ;say that we just did a program.
print_name_2:
ret
print_test:
;
; See if we have reached the last TSR yet.
;
mov di,offset phd_fcb1+1 ;point to their filename.
call compare
jne print_test_1 ;go if they're different.
mov not_yet_flag,'.' ;print the next one.
print_test_1:
ret
print_tsr:
mov di,offset phd_fcb1+1 ;point to their filename.
mov si,bp
print_tsr_0:
lodsb ;print_tsr_ two characters.
call tolower
mov cs:[di],al
inc di
cmp al,'.' ;success when we hit the extension.
jne print_tsr_0
ret
prompt:
assume ds:code
cmp first_one,0 ;do we have a segment yet?
jne prompt_0 ;yes.
mov first_one,dx
prompt_0:
cmp first_one,dx ;is this command.com?
jne prompt_3 ;no - don't print anything.
mov al,phd_fcb1+1 ;if al = '.', then the filename is null.
mov not_yet_flag,al ;if not_yet_flag = '.', print the name.
mov done_one,0 ;say that we haven't done any yet.
;
; Get the first memory block into ES (undocumented).
;
mov ah,52h
int 21h
mov es,es:[bx-2]
;
; Now we step through the phd's (program headers)
;
mov highest_phd,0 ;remember the highest phd we've seen.
prompt_2:
cmp byte ptr es:[0],'M' ;All but the last block start with 'M'.
jne prompt_3
;
; Keep track of the highest phd we've seen, so we don't repeat any.
;
mov ax,es:[1] ;get the phd (owner).
cmp ax,highest_phd ;is this one higher?
jbe prompt_4 ;no - skip it.
mov highest_phd,ax ;yes - remember it.
;
; Now that we've found the next phd, get its environment. However, we have to
; be careful, because some TSRs free their environment memory block in an effort
; to conserve memory. This is good and bad, because freeing their environment
; makes it impossible for us to determine the program name.
;
push ds
mov ds,ax ;point to the phd.
mov bx,phd_environ ;get the environment.
dec bx
mov ds,bx ;point to its header.
cmp ds:[1],ax ;do we still own this memory block?
jne prompt_8 ;no - forget it.
;
; Now skip to the end of the environment where the program name is kept.
;
mov si,16-1 ;look for the end of all the strings.
prompt_5:
inc si
cmp word ptr [si],0 ;did we hit the end yet?
jne prompt_5
add si,4 ;point to the name of the program.
call print_name
prompt_8:
pop ds
;
; Skip to the next memory block.
;
prompt_4:
mov ax,es ;add the size of this memory block
add ax,es:[3] ; to get to the next segment.
inc ax
mov es,ax
jmp prompt_2
prompt_3:
mov went_tsr,0 ;Okay, we're done with TSRs.
ret
assume ds:nothing
their_27 dd ? ;remember what their interrupt 27 was.
our_27:
pushf ;save the flags just in case.
inc went_tsr
popf
jmp their_27
their_21 dd ? ;remember what their interrupt 21 was.
our_21:
;
; Check for buffered input, and save everything if we've got one.
;
pushf
cmp ah,31h ;TSR call?
jne our_21_2
inc went_tsr ;yes - remember it.
our_21_2:
cmp ah,0ah ;buffered input?
jnz our_21_1
push ax
push bx ;save regs
push cx
push dx
push si
push di
push bp
push ds
push es
mov dx,ds ;remember their buffer's segment in dx.
mov ax,cs ;set up ds
mov ds,ax
call prompt
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
our_21_1:
popf
jmp cs:their_21
start_1:
;
; Check for MS-LOSS 3.x
;
mov ah,30h
int 21h
cmp al,3
jae start_3
mov dx,offset bad_ver_msg
mov ah,9
int 21h
int 20h
start_3:
;
; Terminate the filename in phd_fcb1 with '.' instead of ' '.
;
mov si,offset phd_fcb1+1 ;point to their filename.
start_2:
lodsb
cmp al,' '
jne start_2
mov byte ptr ds:[si-1],'.' ;put a period after the filename.
;
; Intercept interrupt 21.
;
mov ax,3521h
int 21h
mov word ptr their_21,bx
mov word ptr their_21+2,es
mov dx,offset our_21
mov ax,2521h
int 21h
;
; Intercept interrupt 27.
;
mov ax,3527h
int 21h
mov word ptr their_27,bx
mov word ptr their_27+2,es
mov dx,offset our_27
mov ax,2527h
int 21h
;
; and TSR.
;
mov dx,offset start_1+15
shr dx,1
shr dx,1
shr dx,1
shr dx,1
mov ah,31h
int 21h
bad_ver_msg db "Requires MS-LOSS 3.x or greater$"
code ends
end start